
#include <BChangeEvent>
#include <BStyle>

#include <BFileDialog>
#include "member_BFileDialog.h"

using namespace BWE;

#define member					(*(member_BFileDialog*)_ptr)
#define member_allocate()		_ptr = new member_BFileDialog(this)
#define member_release()		delete (member_BFileDialog*)_ptr

BFileDialog* GetFileDialog()
{
	static BHolder<BFileDialog> fileDialog = new BFileDialog();
	fileDialog->setModal(true);
	return fileDialog;
}

BString BFileDialog::OpenFolder(BWidget *parent, const BString &title, const BString &dir)
{
	BFileDialog* fd = GetFileDialog();
	fd->setParent(parent);
	fd->setTitle(title);
	if (dir.size())
		fd->setPath(dir);
	fd->setFilterFlag(Attrib_Folder);
	fd->setSelectMultiple(false);
	fd->execute();
	return fd->filePath();
}
BString BFileDialog::OpenFileName(BWidget *parent, const BString &title, const BString &dir, const BString &filter, BString selectedFilter)
{
	BFileDialog* fd = GetFileDialog();
	fd->setParent(parent);
	fd->setTitle(title);
	if (dir.size())
		fd->setPath(dir);
	fd->setFilterFlag(Attrib_File);
	fd->setSelectMultiple(false);
	fd->execute();
	return fd->fileName();
}
BStringList BFileDialog::OpenFileNames(BWidget *parent, const BString &title, const BString &dir, const BString &filter, BString selectedFilter)
{
	BFileDialog* fd = GetFileDialog();
	fd->setParent(parent);
	fd->setTitle(title);
	if (dir.size())
		fd->setPath(dir);
	fd->setFilterFlag(Attrib_All);
	fd->setSelectMultiple(true);
	fd->execute();
	return fd->filePathList();
}
BStringList BFileDialog::SaveFileName(BWidget *parent, const BString &title, const BString &dir, const BString &filter, BString selectedFilter)
{
	BFileDialog* fd = GetFileDialog();
	fd->setParent(parent);
	fd->setTitle(title);
	if (dir.size())
		fd->setPath(dir);
	fd->setFilterFlag(Attrib_All);
	fd->setSelectMultiple(true);
	fd->execute();
	return fd->fileNameList();
}

BFileDialog::BFileDialog(BWidget* parent) : BDialog(parent)
{
	member_allocate();
	this->setSize(800, 560);
}
BFileDialog::~BFileDialog()
{
	member_release();
}

void BFileDialog::setFilterFlag(EntryFlag filterFlag)
{
	if (member.filterFlag != filterFlag)
	{
		member.filterFlag = filterFlag;
		member.slotCurrentChanged(0, 0);
	}
}
EntryFlag BFileDialog::filterFlag() const
{
	return member.filterFlag;
}

void BFileDialog::setFilterDesc(const BString& filterDesc)
{
	if (member.filterDesc != filterDesc)
	{
		member.filterDesc = filterDesc;
		member.slotCurrentChanged(0, 0);
	}
}
const BString& BFileDialog::filterDesc() const
{
	return member.filterDesc;
}

void BFileDialog::setSelectFlag(EntryFlag selectFlag)
{
	if (member.selectFlag != selectFlag)
	{
		member.selectFlag = selectFlag;
		member.fileNameEdit->setText(BString());
	}
}
EntryFlag BFileDialog::selectFlag() const
{
	return member.selectFlag;
}

void BFileDialog::setSelectMultiple(bool selectMultiple)
{
	if (member.selectMultiple != selectMultiple)
	{
		member.selectMultiple = selectMultiple;
		member.tableWidget->setSelectMultiple(selectMultiple);
	}
}
bool BFileDialog::selectMultiple() const
{
	return member.selectMultiple;
}

void BFileDialog::setPath(const BString& path)
{
	member.locate(path);
}
const BString& BFileDialog::path() const
{
	return member.pathComboBox->currentText();
}

const BString& BFileDialog::fileName() const
{
	return member.fileNames.first();
}
const BString& BFileDialog::filePath() const
{
	return member.filePaths.first();
}
const BStringList& BFileDialog::fileNameList() const
{
	return member.fileNames;
}
const BStringList& BFileDialog::filePathList() const
{
	return member.filePaths;
}

void BFileDialog::styleEvent(const BEvent& event)
{
	BDialog::styleEvent(event);
	BStyle* style = this->realStyle();
	member.style = style;
	member.dirtyStyle = true;
	member.okButton->setIcon(style->icon("button-ok"));
	member.cancleButton->setIcon(style->icon("button-cancel"));
}
void BFileDialog::freshEvent(const BEvent& event)
{
	BDialog::freshEvent(event);
	if (member.dirtyStyle)
	{
		for (int i = 0; i < member.treeWidget->topItemCount(); i++)
		{
			member.freshTreeItemImage(member.treeWidget->topItem(i));
		}
		member.freshTableItemImage();
		member.dirtyStyle = false;
	}
}
void BFileDialog::showEvent(const BEvent& event)
{
	BDialog::showEvent(event);
	if (member.pathComboBox->currentText().empty())
	{
		BString current = BFolder::Current();
		member.locate(current);
	}
}
